/**
*    Copyright (C) 2008  Chase Kernan 
*    chase.kernan@gmail.com
*
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
* 
*/

package com.chasekernan.hxnova.core.battles;

import com.chasekernan.hxnova.core.fleets.Fleet;
import com.chasekernan.hxnova.server.functions.battles.BattleStack;
import com.chasekernan.hxnova.utils.IntVector;
import com.chasekernan.hxnova.server.functions.battles.Battles;
import com.chasekernan.hxnova.core.players.Player;
import com.chasekernan.hxnova.core.stars.Star;
import com.chasekernan.hxnova.core.designs.HullDesign;

enum BattleEvent {
    StartRound(round : Int);
    StackMove(stack : BattleStack, to : IntVector);
    WeaponFire(stack : BattleStack, slot : DesignPart, target : BattleStack);
    DamageDone(stack : BattleStack, armor : Float, shields : Float);
    ShipsDestroyed(stack : BattleStack, number : Int);
    StackDestroyed(stack : BattleStack);
    StackDisengage(stack : BattleStack);
    MissileMissed(stack : BattleStack, slot : DesignPart, 
                  target : BattleStack);
}

/**
    Holds all of the details of a battle.
**/
class BattleRecord {
    
    /**
        Contains all of the stacks present at the start of the battle.
    **/
    public var stacks : Array<BattleStack>;
    
    /**
        Contains a list of the events in the battle, in the order that they
        occurred.
    **/
    public var events : List<BattleEvent>;
    
    /**
        Contains the stacks that are left over at the end of the battle.
    **/
    public var finalStacks : Array<BattleStack>;
    
    /**
        The players involved in the battle;
    **/
    public var players : List<Player>;
    
    /**
        Creates a new battle record with the stacks present at the start of the
        battle and the players represented by those ships.
    **/
    public function new(initialStacks : Array<BattleStack>, 
                        playersInvolved : List<Player>) {
        stacks = initialStacks.copy();
        events = new List();
        finalStacks = new Array();
        players = playersInvolved;
    }
    
    /**
        Adds the event to the list of events in the battle as the latest event
        that has occurred.
    **/
    public function recordEvent(event : BattleEvent) {
        events.push(event);
    }
    
    /**
        Sets the battle to be over with the stacks given to be the only 
        survivors.
    **/
    public function finalizeBattle(survivors : Array<BattleStack>) {
        finalStacks = survivors.copy();
    }
    
    /**
        Returns the number of unarmed ships in the battle.
    **/
    public function getUnarmedShipCount() : Int {
        var sum = 0;
        for (stack in stacks) {
            if (!stack.type.hasWeapons()) sum += stack.amount;
        }
        return sum;
    }
    
    /**
        Returns the total number of ships in the battle.
    **/
    public function getShipCount() : Int {
        var sum = 0;
        for (stack in stacks) sum += stack.amount;
        return sum;
    }
    
    /**
        Returns true if there's a starbase involved.
    **/
    public function hasStarbase() : Bool {
        for (stack in stacks) {
            if (stack.type.isStarbase()) return true;
        }
        
        return false;
    }
    
    /**
        Returns the number of armed ships in the battle.
    **/
    public function getArmedShipCount() : Int {
        var sum = 0;
        for (stack in stacks) {
            if (stack.type.hasWeapons()) sum += stack.amount;
        }
        return sum;
    }
    
    /** 
        Returns the number of bombers in the battle;
    **/
    public function getBomberCount() : Int {
        var sum = 0;
        for (stack in stacks) {
            if (stack.type.hasBombingCapabilities()) sum += stack.amount;
        }
        return sum;
    }
    
    /** 
        Returns the number of fuel transports in the battle.
    **/
    public function getFuelTransportCount() : Int {
        var sum = 0;
        for (stack in stacks) {
            
            if (stack.type.getFuelCapacity() > 
                    stack.type.baseHull.fuelCapacity) {
                        
                sum += stack.amount;
                //TODO: Hulls that are specifically designed to carry fuel need
                //to be added here.
            }
        }
        return sum;
    }
    
    /** 
        Returns the number of frieghters in the battle;
    **/
    public function getFrieghterCount() : Int {
        var sum = 0;
        for (stack in stacks) {
            if (stack.type.getCargoCapacity() > 0) sum += stack.amount;
        }
        return sum;
    }
    
    
        
}